#define _CRT_SECURE_NO_WARNINGS
#define ROW 3
#define COL 3
#define PLYER_CHESS_PIECES 'o'
#define COMPUTER_CHESS_PIECES 'x'
#define CONTINUE 'c'
#define PEASE 'p'

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void menu(void);
void InitChessboard(char(*p)[ROW], char ch, int x, int y);    // 二维数组初始化函数
void DisplayChessboard(char(*p)[ROW], int x, int y);  // 棋盘打印函数
void PlayerMove(char(*p)[ROW], int x, int y);	// 玩家下棋
void MachineMove(char(*p)[3], int x, int y);	// 电脑下棋
int  isNotNULL(char arr[][ROW], int x, int y);  // 还有空格下棋
char isWin(char arr[][COL], int x, int y);		// 获胜
void game(void);								//流


int main()
{
	srand((size_t)time(NULL));
	int flag = 0;
	do 
	{
		menu(); // 打印菜单
		printf("input : ");
		scanf("%d", &flag);
		switch (flag)
		{
		case 1:
			printf("---------------  三子棋  ----------------\n\n");
			game();
			break;
		case 0:
			printf("退出游戏!!!\n");
			break;
		default:
			printf("输入错误!!!\n");
			break;
		}
	} while (flag);
	return 0;
}

void menu(void)
{
	printf("**********************************\n");
	printf("*********   1：start     *********\n");
	printf("*********   0：exit      *********\n");
	printf("**********************************\n");
}
void InitChessboard(char(*p)[ROW], char ch, int x, int y)    // 二维数组初始化函数
{
	int i = 0, j = 0;
	for (i = 0; i < x; i++)
		for (j = 0; j < y; j++)
			(*(p + i))[j] = ch;
}
void DisplayChessboard(char(*p)[ROW], int x, int y)   // 棋盘打印函数
{
	int i = 0, j = 0;
	for (i = 0; i < x; i++)
	{
		for (j = 0; j < y; j++)
		{
			printf(" %c ", (*(p + i))[j]);
			if (j != y - 1)
				putchar('|');
			else
				putchar('\n');
		}
		if (i != x - 1)
		{
			for (j = 0; j < y; j++)
			{
				printf("---");
				if (j != y - 1)
					putchar('|');
				else
					putchar('\n');
			}
		}
	}
	printf("\n");
}

void PlayerMove(char(*p)[ROW], int x, int y)
{

	int r = 0, c = 0;
	printf("输入你要放置棋子的位置的行号和列号：");
	while (1)
	{
		scanf("%d %d", &r, &c);
		if ((r >= 0 && r <= ROW) && (c >= 0 && c <= ROW)) // 下标合法
		{

			if ((*(p + r - 1))[c - 1] != ' ')
				printf("该位置已被占用,请重新输入：");
			else
			{
				(*(p + r - 1))[c - 1] = PLYER_CHESS_PIECES;
				break;
			}
		}
		else
			printf("下标无效，请重新输入：");
	}
}

void MachineMove(char(*p)[ROW], int x, int y)
{
	int rx = 0, ry = 0;
	printf("电脑下棋：\n");
	// 随机产生下标

	// 判断
	while (1)
	{
		rx = rand() % ROW;
		ry = rand() % ROW;

		if (p[rx][ry] == ' ')
		{
			(*(p + rx))[ry] = COMPUTER_CHESS_PIECES;
			break;
		}
	}
}

int  isNotNULL(char arr[][ROW], int x, int y)
{
	int i = 0, j = 0;
	for (i = 0; i < x; i++)
		for (j = 0; j < y; j++)
			if (arr[i][j] == ' ')
				return 0;
	return 1;
}

char isWin(char arr[][COL], int x, int y)
{
	// 判断行
	for (int i = 0; i < ROW; i++)
	{
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][1] != ' ')
			return arr[i][0];
	}
	// 判断列
	for (int i = 0; i < ROW; i++)
	{
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[1][i] != ' ')
			return arr[1][i];
	}
	// 判断对角线
	if (arr[0][0] == arr[1][1] && arr[2][2] == arr[1][1] && arr[1][1] != ' ')
		return arr[1][1];
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
		return arr[1][1];
	if (isNotNULL(arr, x, y))
	{
		return PEASE;
	}
	return CONTINUE;
}
void game(void)
{
	char flag = '\0';
	char chessboard[ROW][COL] = { 0 };
	InitChessboard(chessboard, '\40', ROW, COL);   // 初始化棋盘
	DisplayChessboard(chessboard, ROW, COL);    // 打印棋盘

	while (1)
	{

		PlayerMove(chessboard, ROW, COL);       	// 玩家下棋
		DisplayChessboard(chessboard, ROW, COL);    // 打印棋盘
		flag = isWin(chessboard, ROW, COL);					// 判断输赢
		if (flag != CONTINUE)
			break;
		MachineMove(chessboard, ROW, COL);			// 机器下棋
		DisplayChessboard(chessboard, ROW, COL);    // 打印棋盘
		flag = isWin(chessboard, ROW, COL);					// 判断输赢
		if (flag != CONTINUE)
			break;
	}
	switch (flag)
	{
	case PLYER_CHESS_PIECES:
		printf("---------------  三子棋  ----------------\n\n");
		printf("玩家获胜。\n");
		break;
	case COMPUTER_CHESS_PIECES:
		printf("---------------  三子棋  ----------------\n\n");
		printf("电脑获胜。\n");
		break;
	case PEASE:
		printf("---------------  三子棋  ----------------\n\n");
		printf("平局。\n");
		break;
	}
	DisplayChessboard(chessboard, ROW, COL);
}
